from flask import Blueprint,jsonify,request
from conf.comm import sqlalchemy_context
# 密码加密
from werkzeug.security import generate_password_hash,check_password_hash
from database import *
import json
import re
from utils.redisconn import r
import random
from utils.ronglianyun import send_message
# 生成token  自己封装得
from utils.jwt_token import myjwt
import os
import uuid
# from utils.jwt_token import mytoken
#蓝图初始化
bp_users = Blueprint('users',__name__)
#注册功能实现
@bp_users.route('/reg/',methods=['POST'])
@sqlalchemy_context()
def reg():
    data = request.data
    if not data:
        data = request.form
    else:
        # 获取用户输入
        data = json.loads(request.data)
    
    # 正则验证
    reg = re.match('^1[3-9]\d{9}$',data['mobile'])
    if not reg:
        return jsonify({"code":10012,"mes":'手机号不合法'})
    try:
        user = User(username=data['username'],password=generate_password_hash(data['password']),mobile=data['mobile'])
        db.session.add(user)
        db.session.commit()
        return jsonify({'code':200})
    except:
        return jsonify({'code':10010})

@bp_users.route('/login/',methods=['GET','POST'])
@sqlalchemy_context()
def login():
    username = request.args.get('username')
    password = request.args.get("password")
    mobile = request.args.get('mobile')
    
    if username:
        user = User.query.filter_by(username=username).first()
        start = datetime.datetime.now() #qwe
        if user:
            if check_password_hash(user.password,password):
                # token = mytoken.encode_jwt({'id':user.id,'username':user.username})
                token = myjwt.jwt_encode({'data':{'id':user.id,'username':user.username}})
                return jsonify({"code":200,'userid':user.id,'username':user.username,'token':token})
            else:
                gettwice = Twice.query.filter_by(username=username).first()
                if not gettwice:
                    twice = Twice(username=username,ctwice=1)
                    db.session.add(twice)
                    db.session.commit() 
                else:
                    if start.timestamp()/3600>=gettwice.stime.timestamp() / 3600 + 24:
                        Twice.query.filter_by(username=username).update({'count': 0, 'stime': start})
                        db.session.commit()
                    if gettwice.ctwice<3:
                        Twice.query.filter_by(username=username).update({'ctwice':gettwice.ctwice+1})
                        db.session.commit()
                    else:
                        return jsonify({"code": 12345,'mes':'密码只能输入三次'})
        return jsonify({"code":10013,'mes':'账号或密码错误'})
    else:
        mob = re.match('^1[3-9]\d{9}$',mobile)
        if not mob:
            return jsonify({"code":20010,'mes':'手机号不合法'})
        if mobile=='':
            return jsonify({"code":20011,'mes':'手机号不能为空'})
        # 是否30秒内发送过验证码
        code = r.get_str(mobile)
        if code:
            return jsonify({"code":20020,'mes':'发送频繁'})
        code = random.randint(100000,666666)  
        #调用容联云短信接口
        flag = send_message(mobile, code, 1)
        if flag:
            #发送成功 存redis中
            r.set_str(mobile, code,60)
            #返回结果
            return jsonify({"code":200,'smscode':code,'mes':'发送成功'})
        else:
            return jsonify({"code":20012,'mes':"发送失败 请重试"})

@bp_users.route('/mobile_login/',methods=['POST'])
@sqlalchemy_context()
def mobile_login():
    data = request.data
    if data:
        data = json.loads(data)
    else:
        data = request.form
    # 获取手机号 验证码
    mobile = data['mobile']
    code = data['code']
    # 判断手机号是否合法
    mob = re.match('^1[3-9]\d{9}$',mobile)
    if not mob:
        return jsonify({"code":20013,'mes':'手机号不合法'}) 
    if mobile=='':
        return jsonify({"code":20014,'mes':'手机号不能为空'})
    # 根据手机号区redis表中查找验证码
    rcode = r.get_str(mobile)
    
    # 找到进行判断
    if rcode:
        if int(rcode)==int(code):
            # 如果判断 相等  则根据手机号查找
            user = User.query.filter_by(mobile=mobile).first()
            # 如果user对象不存在 然后添加一个数据
            if not user:
                user = User(username=mobile,mobile=mobile)
                db.session.add(user)
                db.session.commit()
            else:
                # 不存在直接返回 然后把redis中得验证码删除
                r.del_str(mobile)
            # token = mytoken.encode_jwt({'id':user.id,'username':user.username})
            token = myjwt.jwt_encode({'data':{'id':user.id,'username':user.username}})
            return jsonify({"code":200,'userid':user.id,'username':user.username,'token':token})
            # 如果没不相等 则验证码错误
        else:
            return jsonify({"code":20016,'mes':'验证码错误 重新输入'})
    # 如果没找到rcode 然后让用户重新发送
    else:
        return jsonify({"code":20015,'mes':'验证失效，请重新发送'})

        
# 用户信息 接口
@bp_users.route('/getuserinfo/')
@sqlalchemy_context()
def getuserinfo():
        id = request.args.get('userid')
        # 数据库查找
        user = User.query.filter_by(id=id).first()
        dict1={}
        dict1['username']=user.username
        dict1['mobile'] = user.mobile
        dict1['avater'] = user.avater
        # return 'ok'
        return jsonify({'code':200,'dict1':dict1})

# 请求前 前端头部携带token过来 然后判断
@bp_users.before_request
def before_request():
    # 白名单 如果在白名单里   则直接忽略 否则接受头部token  然后解密 对比
    list1 = ['/users/login/','/users/reg/','/users/mobile_login/']
    # print(request.path)    获取路由
    if request.path not in list1:
    # 获取token
        try:
            token = request.headers['token']
        except:
            return jsonify({'code':403,'mes':'请传递token'})
        # 解密 重新对比token
        newtoken = myjwt.jwt_decode(token)
        if  newtoken and  myjwt.check(token, newtoken):
            pass
        else:
            # 返回
            return jsonify({"code":403,'mes':'您无权访问'}) 


# 用户中心接口
@bp_users.route('/uploda/',methods=['POST'])
@sqlalchemy_context()
def uploda():
    # 获取文件
    file = request.files['file']
    # 上传到uploda文件夹中
    # 解决文件名被覆盖
    #1. 文件名重命名  文件名.后缀 1.jpg   后缀不变 变文件名
    # 获取文件后缀
    filetext = os.path.splitext(file.filename)[1]
    newfile = uuid.uuid4().hex + filetext  # 前面新生成得文件名拼接后缀


    #2. 在upload下面建立文件夹专业存文件夹名为userid
    userid = request.form.get("userid")
    # 根据userid创建文件夹
    # 判断此用户得文件夹是否存在 存在就不用创建 直接写文件  不存在则创建
    path= './static/upload/'+str(userid)
    if not os.path.exists(path):  # 如果用户文件夹不存在
        os.mkdir(path)
    # 保存到  /static/upload/文件夹中
    file.save(os.path.join(path,newfile))

    # 更新到数据库
    User.query.filter_by(id=userid).update({"avater":newfile})
    db.session.commit()
    return jsonify({"code":200,'filename':newfile})
